package initialize

import (
	"fmt"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
	"html/template"
	"reflect"
	"vueBasic/global"
	"vueBasic/middleware"
	"vueBasic/router"
)

// 启动项目
func InitEnter() error {
	//r := gin.New() 用于接口
	r := gin.Default()
	//配置gin允许跨域请求
	r.Use(middleware.Cors(), middleware.GinRecovery()) //TODO 后期可以异常捕获和限流器中间件
	//注册全局模板函数 注意顺序，注册模板函数需要在加载模板上面（需要定义你设置的函数）
	r.SetFuncMap(template.FuncMap{})
	//加载模板 放在配置路由前面
	r.LoadHTMLGlob("public/templates/**/**/*")
	////配置静态web目录 第一个参数表示路由 第二个参数表示映射的目录
	r.Static("/static", "./public/static")
	r.Static("/uploads", "./public/uploads")

	//访问日志中间件
	if global.CONF.System.AccessLogStatus {
		r.Use(middleware.AccessLog())
	}

	r.GET("/health", func(c *gin.Context) {
		c.JSON(200, "ok")
	})
	//(用于内联页面，前后分离项目可以去掉,放在路由前) 创建基于 cookie 的存储引擎，tiedong 参数是用于加密的密钥
	store := cookie.NewStore([]byte("tiedong"))
	//jwtConfig := global.CONF.AdminJwt
	//store.Options(sessions.Options{MaxAge: conv.Int(jwtConfig.ExpiresTime)}) //设置缓存时间
	//配置session的中间件 store是前面创建的存储引擎，我们可以替换成其他存储引擎
	r.Use(sessions.Sessions("mysession", store))

	//注册admin路由(利用reflect反射的MethodByName获取函数名，然后将函数名.Interface()转换为接口类型变量，
	//最后使用类型断言进行转换)
	for _, ctrl := range router.AdminRouter {
		router := reflect.ValueOf(ctrl).MethodByName("Router")
		callback := router.Interface().(func(r *gin.RouterGroup))
		callback(r.Group(""))
	}

	//启动端口 (适用于对接前后分离启动项目)
	//server := &http.Server{
	//	Addr:           fmt.Sprintf(":%d", global.CONF.Server.Port),
	//	Handler:        r,
	//	ReadTimeout:    60 * time.Second,
	//	WriteTimeout:   60 * time.Second,
	//	MaxHeaderBytes: 1 << 20,
	//}
	//err := server.ListenAndServe()
	err := r.Run(fmt.Sprintf(":%d", global.CONF.System.Port))
	return err
}
